package com.spark.lola.hander;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.spark.lola.entity.statistics.StatisticsStoreProduct;
import com.spark.lola.entity.warehouse.StoreInfo;
import com.spark.lola.mapper.StatisticsStoreProductMapper;
import com.spark.lola.service.IStoreInfoService;
import com.spark.lola.support.common.util.DatesUtil;
import com.spark.lola.support.common.util.ResponseBean;
import com.spark.lola.support.common.util.TimeUtil;
import com.spark.lola.support.core.constant.TimeConstant;
import com.spark.lola.support.mybatis.common.QueryCondition;
import com.spark.lola.support.mybatis.entity.QueryParam;
import com.spark.lola.support.netty.annotation.HawkBean;
import com.spark.lola.support.netty.annotation.HawkMethod;
import com.spark.lola.support.netty.api.NettyPermissionService;
import com.spark.lola.support.netty.constant.NettyCommands;
import com.spark.lola.support.wms.constant.StatisticsGroupType;
import com.spark.lola.support.wms.constant.WmsNettyCommands;
import com.spark.lola.vo.StoreProductsVo;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import java.net.InetSocketAddress;
import java.sql.Time;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购大屏 socket服务
 * @Author: DengYeJun
 * @Date: 2020/6/12 15:27
 */
@HawkBean
public class WarehouseHandler {
    private static final Logger logger = LoggerFactory.getLogger(WarehouseHandler.class);
    @Autowired
    NettyPermissionService nettyPermissionService;

    @Autowired
    private StatisticsStoreProductMapper statisticsStoreProductMapper;
    @Autowired
    private IStoreInfoService storeInfoService;

    /**
     * 查询货品类目统计
     */
    @HawkMethod(cmd = WmsNettyCommands.QUERY_WAREHOUSE_PRODUCT_STATISTICS,version = NettyCommands.COMMANDS_VERSION)
    public String queryProductStatistics(long seqId, byte[] body, ChannelHandlerContext ctx) {
        InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        // 获取时间类型
        String json = new String(body);
        JSONObject request = JSON.parseObject(json);
        String timeType = request.getString("timeType");
        String channelId = ctx.channel().id().asLongText();
        // 获取用户ID
        String userId = nettyPermissionService.getUserId(channelId);
        logger.info("管理员【{}】通道【{}】参数【{}】请求货品类目统计概况", userId, channelId,timeType);

        int groupType = StatisticsGroupType.DAY;
        if(timeType.equals(TimeConstant.MONTH)){
            groupType = StatisticsGroupType.MONTH;
        }
        if(timeType.equals(TimeConstant.WEEK)){
            groupType = StatisticsGroupType.SLEF;
        }
        QueryParam<StatisticsStoreProduct> query =new QueryParam<>();
        query.setSortFields("orderWeight_d");
        query.setPageSize(1000);
        query.getQueryList().addAll(bindParams(timeType));
        Page<StatisticsStoreProduct> page = statisticsStoreProductMapper.productPage(query.toPageParam().getPage(), groupType,query.toPageParam().getEntityWrapper());
        return JSON.toJSONString(ResponseBean.success(page.getRecords()));
    }

    /**
     * 查询仓库货品
     */
    @HawkMethod(cmd = WmsNettyCommands.QUERY_WAREHOUSE_STORE_PRODUCT_STATISTICS,version = NettyCommands.COMMANDS_VERSION)
    public String queryStoreProductStatistics(long seqId, byte[] body, ChannelHandlerContext ctx) {
        InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        // 获取时间类型
        String json = new String(body);
        JSONObject request = JSON.parseObject(json);
        String timeType = request.getString("timeType");
        String channelId = ctx.channel().id().asLongText();
        // 获取用户ID
        String userId = nettyPermissionService.getUserId(channelId);
        logger.info("管理员【{}】通道【{}】参数【{}】请求仓库货品类目统计概况", userId, channelId,timeType);
        // 获取仓库列表
        List<StoreInfo> storeInfos = storeInfoService.getStores();
        if(CollectionUtils.isEmpty(storeInfos)) {
            return JSON.toJSONString(ResponseBean.error("无数据"));
        }
        // 获取所有仓库货品数据
        int groupType = StatisticsGroupType.DAY;
        if(timeType.equals(TimeConstant.MONTH)){
            groupType = StatisticsGroupType.MONTH;
        }
        if(timeType.equals(TimeConstant.WEEK)){
            groupType = StatisticsGroupType.SLEF;
        }
        QueryParam<StatisticsStoreProduct> query =new QueryParam<>();
        query.setSortFields("orderWeight_d");
        query.setPageSize(1000);
        query.getQueryList().addAll(bindParams(timeType));
        Page<StatisticsStoreProduct> page = statisticsStoreProductMapper.page(query.toPageParam().getPage(), groupType,query.toPageParam().getEntityWrapper());

        Map<Long,List<StatisticsStoreProduct>> storeMap =new HashMap<>();
        storeInfos.forEach(o->storeMap.put(o.getId(),new ArrayList<>()));
        // 拼装结果集
        List<StoreProductsVo> lst =new ArrayList<>();
        if(!CollectionUtils.isEmpty(page.getRecords())) {
            page.getRecords().forEach(o -> {
                if (storeMap.containsKey(o.getStoreId())) {
                    List<StatisticsStoreProduct> details =storeMap.get(o.getStoreId());
                    details.add(o);
                    storeMap.put(o.getStoreId(),details);
                }
            });
        }
        for(StoreInfo storeInfo :storeInfos){
            StoreProductsVo vo =new StoreProductsVo(storeInfo);
            vo.setDetails(storeMap.get(storeInfo.getId()));
            lst.add(vo);
        }
        return JSON.toJSONString(ResponseBean.success(lst));
    }

    private static List<QueryCondition> bindParams(String timeType){
        String[] times = parseTime(timeType);
        List<QueryCondition> query =new ArrayList<>();
        switch (timeType){
            case TimeConstant.TODAY: {
                QueryCondition queryCondition = new QueryCondition();
                queryCondition.setKey("createDate");
                queryCondition.setOper("=");
                queryCondition.setValue(TimeUtil.getCurrentDate());
                query.add(queryCondition);
                break;
            }
            case TimeConstant.WEEK: {
                QueryCondition start = new QueryCondition();
                start.setKey("createDate");
                start.setOper(">=");
                start.setValue(times[0]);
                QueryCondition end = new QueryCondition();
                end.setKey("createDate");
                end.setOper("<=");
                end.setValue(times[1]);
                query.add(start);
                query.add(end);
                break;
            }
            case TimeConstant.MONTH: {
                QueryCondition queryCondition = new QueryCondition();
                queryCondition.setKey("createMonth");
                queryCondition.setOper("=");
                queryCondition.setValue(TimeUtil.getMonth(new Date()));
                query.add(queryCondition);
                break;
            }
            default:
                break;
        }
        return query;
    }

    private static String[] parseTime(String timeType){
        String[] times = new String[2];
        Date now = new Date();
        switch (timeType) {
            case TimeConstant.TODAY:
                times[0] = TimeUtil.getStartOfDay(now);
                times[1] = TimeUtil.getEndOfDay(now);
                break;
            case TimeConstant.YESTERDAY:
                break;
            case TimeConstant.WEEK:
                times[0] = TimeUtil.getTime(DatesUtil.getBeginDayOfWeek());
                times[1] = TimeUtil.getTime(DatesUtil.getEndDayOfWeek());
                break;
            case TimeConstant.MONTH:
                times = TimeUtil.daysOfMonth();
                break;
            case TimeConstant.YEAR:
                times[0] = TimeUtil.getTime(DatesUtil.getBeginDayOfYear());
                times[1] = TimeUtil.getTime(DatesUtil.getEndDayOfYear());
                break;
            default:
                break;
        }
        return times;
    }


    public static void main(String[] args){
//        String[] times = parseTime(TimeConstant.YEAR);
//        for (String time : times) {
//            System.out.println((new SimpleDateFormat("yyyy-MM-dd 00:00:00")).format(new Date()));
//        }
        System.out.println(JSON.toJSONString(bindParams(TimeConstant.MONTH)));
    }
}
